package com.example.teaching_server.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

/**
 * 分页数据DTO
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "分页响应数据")
public class PageDTO<T> {

    @NotNull(message = "数据项列表不能为空")
    @Schema(description = "当前页数据项列表", requiredMode = Schema.RequiredMode.REQUIRED)
    private List<T> items;

    @Positive(message = "总记录数必须为正数")
    @Schema(description = "总记录数", example = "150", requiredMode = Schema.RequiredMode.REQUIRED)
    private long total;

    @Positive(message = "页码必须大于0")
    @Schema(description = "当前页码（从1开始）", example = "1", requiredMode = Schema.RequiredMode.REQUIRED)
    private int page;

    @Positive(message = "每页大小必须大于0")
    @Schema(description = "每页记录数", example = "20", requiredMode = Schema.RequiredMode.REQUIRED)
    private int size;

    @Schema(description = "总页数", example = "8")
    private int totalPages;

    @Schema(description = "是否有上一页", example = "true")
    private boolean hasPrevious;

    @Schema(description = "是否有下一页", example = "false")
    private boolean hasNext;

    /**
     * 构建分页响应
     */
    public static <T> PageDTO<T> of(List<T> items, long total, int page, int size) {
        int totalPages = (int) Math.ceil((double) total / size);

        return PageDTO.<T>builder()
                .items(items)
                .total(total)
                .page(page)
                .size(size)
                .totalPages(totalPages)
                .hasPrevious(page > 1)
                .hasNext(page < totalPages)
                .build();
    }

    /**
     * 构建空分页响应
     */
    public static <T> PageDTO<T> empty(int page, int size) {
        return PageDTO.<T>builder()
                .items(List.of())
                .total(0)
                .page(page)
                .size(size)
                .totalPages(0)
                .hasPrevious(false)
                .hasNext(false)
                .build();
    }

    /**
     * 获取起始记录索引
     */
    @Schema(description = "起始记录索引", accessMode = Schema.AccessMode.READ_ONLY)
    public int getStartIndex() {
        return (page - 1) * size;
    }

    /**
     * 获取结束记录索引
     */
    @Schema(description = "结束记录索引", accessMode = Schema.AccessMode.READ_ONLY)
    public int getEndIndex() {
        return Math.min(page * size, (int) total);
    }

    /**
     * 获取当前页记录数量
     */
    @Schema(description = "当前页记录数量", accessMode = Schema.AccessMode.READ_ONLY)
    public int getCurrentPageSize() {
        return items != null ? items.size() : 0;
    }

    /**
     * 验证分页参数是否有效
     */
    @Schema(description = "分页参数是否有效", accessMode = Schema.AccessMode.READ_ONLY)
    public boolean isValid() {
        return page > 0 && size > 0 && total >= 0 && items != null;
    }

    /**
     * 获取分页摘要信息
     */
    @Schema(description = "分页摘要信息", accessMode = Schema.AccessMode.READ_ONLY)
    public String getSummary() {
        return String.format("第%d页，共%d条记录，每页%d条，共%d页",
                page, total, size, totalPages);
    }

    /**
     * 获取下一页页码
     */
    @Schema(description = "下一页页码", accessMode = Schema.AccessMode.READ_ONLY)
    public Integer getNextPage() {
        return hasNext ? page + 1 : null;
    }

    /**
     * 获取上一页页码
     */
    @Schema(description = "上一页页码", accessMode = Schema.AccessMode.READ_ONLY)
    public Integer getPreviousPage() {
        return hasPrevious ? page - 1 : null;
    }
}
